#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <thread>

// //线程的局部存储
// __thread int shared_value = 100;

// std::string toHex(pthread_t tid)
// {
//     //4,进程内的函数，线程共享
//     char buffer[64];
//     snprintf(buffer, sizeof(buffer), "0x%lx", tid);
//     return buffer;
// }

// void* start(void* args)
// {
//     std::string name = static_cast<const char*>(args);
//     sleep(1);
//     while(true)
//     {
//         printf("I am a new thread , name: %s, shared_value: %d , &share_value: %p\n", name.c_str(), shared_value, &shared_value );
//         sleep(1);
//     }

//     return nullptr;
// }

// int main()
// {
//     pthread_attr_t attr;

//     pthread_t tid;
//     pthread_create(&tid, nullptr, start, (void*)"thread-1");
//     std::cout<<"I am a new thread, name: main, "<< toHex(pthread_self())
//              <<", NEW thread id: " << toHex(tid) << std::endl;

//     while(true)
//     {
//         printf("main thread ,shared_value: %d, &shared_value: %p\n", shared_value, &shared_value);
//         shared_value += 10;
//         sleep(1);
//     }
//     pthread_join(tid, nullptr);
//     return 0;
// }

// int *addr = nullptr;

// void *start1(void *args)
// {
//     std::string name = static_cast<const char *>(args);
//     int a = 100;
//     while (true)
//     {
//         std::cout << name << " local val a: " << a << std::endl;
//         a += 100;
//         if(1000 == a)
//         {
//             break;
//         }
//         sleep(1);
//     }

//     return nullptr;
// }

// void* start(void* args)
// {
//     // pid_t id = fork();
//     // if(0 == id)
//     // {
//     //     //...
//     // }
//     pthread_detach(pthread_self());
//     std::string name = static_cast<const char* >(args);
//     while(true)
//     {
//         if(addr != nullptr)
//             std::cout<< name << " mod val a: " << (*addr)++ << std::endl;
//         std::cout<< "I am a new thread" <<std::endl;
//         sleep(5);
//         // break;
//     }

//     // return 0;//新线程return 表示线程退出
//     // exit(1);//任何地方调用exit, 表示进程退出！
//     pthread_exit((void*)10);

// }

// int main()
// {
//     // pthread_t tid1, tid2;
//     pthread_t tid;
//     pthread_create(&tid, nullptr, start, (void *)"thread-1");
//     //pthread_detach(tid);

//     sleep(5);

//     int n =  pthread_cancel(tid);
//     std::cout<< "取消线程： "<< tid <<std::endl;

//     void *ret = nullptr;
//     int n = pthread_join(tid, &ret); //
//     std::cout << " new thread exit code: " << (long long int)ret << " , n = " << n << std::endl;

//     return 0;
// }

// #include <queue>

// class ThreadData
// {
// public:
//     ThreadData()
//     {
//     }

//     ThreadData(const std::string &name, int a, int b)
//     {
//         _name = name;
//         _a = a;
//         _b = b;
//     }

//     void Init(const std::string &name, int a, int b)
//     {
//         _name = name;
//         _a = a;
//         _b = b;
//     }

//     void Excute()
//     {
//         _result = _a + _b;
//     }

//     int Result() { return _result; }
//     std::string Name() { return _name; }
//     void SetId(pthread_t tid) { _tid = tid; }
//     pthread_t Id() { return _tid; }
//     int A() { return _a; }
//     int B() { return _b; }

//     ~ThreadData()
//     {
//     }

// private:
//     std::string _name;
//     int _a;
//     int _b;
//     int _result;
//     pthread_t _tid;
// };

// class outData
// {
// };

// // 5全局变量在线程内部是共享的
// int gval = 100;
// std::queue<int> q;
// char buffer[4096];

// #define NUM 10

// std::string toHex(pthread_t tid)
// {
//     // 进程内的函数, 线程共享
//     char tranbuffer[64];
//     snprintf(tranbuffer, sizeof(buffer), "0x%lx", tid);
//     return tranbuffer;
// }

// void *routine(void *args)
// {
//     // std::string name = static_cast<const char *>(args);
//     ThreadData *td = static_cast<ThreadData *>(args);
//     while (true)
//     {
//         // 3,不加保护的情况下， 显示器文件就是共享资源！
//         std::cout << "我是新线程， 我的名字是: " << td->Name()
//                   << ", my tid is : " << toHex(pthread_self())
//                   << ", 全局变量（会修改） : " << gval << std::endl;

//         gval++;
//         td->Excute();
//         sleep(1);
//         break;
//     }

//     // 8，返回值问题：返回参数， 可以是变量， 数字， 对象！
//     //  8.1 理论上， 堆空间也是共享的！ 谁拿着堆空间的入口地址，谁就能访问该堆区
//     //  int* p = new int(10);
//     //  return (void*)p;

//     return td;
// }

// void *routine2(void *args)
// {
//     std::string name = static_cast<const char *>(args);
//     while (true)
//     {
//         // 3,在不加保护的情况下，显示器文件就是共享资源！
//         std::cout << "我是新线程，我的名字是：" << name << ", my tid is : " << toHex(pthread_self()) << ", 全局变量（只是检测）:" << gval << std::endl;
//         sleep(1);
//         // 6, 线程一旦出现异常, 可能会导致其他线程全部崩溃
//         // 6.1信号
//         int *p = nullptr;
//         *p = 100;
//     }

//     // return 0;
// }
// int main()
// {
//     // ThreadData td[NUM];
//     // // 准备我们要加工处理的数据
//     // for (int i = 0; i < NUM; i++)
//     // {
//     //     char id[64];
//     //     snprintf(id, sizeof(id), "thread-%d", i);
//     //     td[i].Init(id, i * 10, i * 20);
//     // }

//     // // 创建多线程
//     // for (int i = 0; i < NUM; i++)
//     // {
//     //     pthread_t id;
//     //     pthread_create(&id, nullptr, routine2, &td[i]);
//     //     td[i].SetId(id);
//     // }

//     // //等待多个线程
//     // for(int i = 0; i < NUM; i++)
//     // {
//     //     pthread_join(td[i].Id(), nullptr);
//     // }

//     // //汇总处理结果
//     // for(int i = 0; i < NUM; i++)
//     // {
//     //     printf("td[%d]: %d+%d=%d[%ld]\n", i, td[i].A(), td[i].B(), td[i].Result(), td[i].Id());
//     // }

//     // 1,新线程和main线程谁先运行，不确定
//     // 2,线程创建出来， 要对进程的时间片进行瓜分
//     // 8,传参问题： 传递参数，可以是变量，数字，对象！

//     pthread_t tid1;
//     ThreadData *td = new ThreadData("thread-1", 10, 20);
//     pthread_create(&tid1, nullptr, routine2, td);

//     // 7,线程创建后也是 要等待和被回收的！
//     // 7.1 理由： a。类似僵尸进程的问题， b, 为了知道新线程的执行结果
//     ThreadData *rtd = nullptr;
//     int n = pthread_join(tid1, (void **)&rtd); // 我们可以保证，执行完毕，任务一定处理完了，结果变量一定已经被写入了！
//     if (n != 0)
//     {
//         std::cerr << "join error: " << n << ", " << strerror(n) << std::endl;
//         return 1;
//     }

//     // std::cout << "join suceess!, ret: " << rtd->Result() << std::endl;
//     // delete td;

//     pthread_t tid2;
//     pthread_create(&tid2, nullptr, routine, (void *)"thread-2");

//     pthread_t tid3;
//     pthread_create(&tid3, nullptr, routine, (void *)"thread-3");

//     pthread_t tid4;
//     pthread_create(&tid4, nullptr, routine2, (void *)"thread-4");

//     std::cout<< "new thread id" << pthread_self() <<std::endl;
//     printf("new thread id : 0x%lx\n", tid1);
//     printf("new thread id : 0x%lx\n", tid2);
//     printf("new thread id : 0x%lx\n", tid3);
//     printf("new thread id : 0x%lx\n", tid4);

//     while(true)
//     {
//         std::cout<< "我是mian线程..." << std::endl;
//         sleep(1);
//     }

//     return 0;
// }

void* routine(void * args)
{
    std::string name = static_cast<const char *>(args);
    while(true)
    {
        std::cout<< "我是新线程 , 我的名字是： " << std::endl;
        sleep(1);
    }

    return 0;
}

int main()
{

    std::thread t([] () {
        while(true)
        {
            std::cout<< "我是新线程， 我的名字 ：new thread " << std::endl;
            sleep(1);
        }
    });

    while(true)
    {
        std::cout<< "我是main线程..." << std::endl;
        sleep(1);
    }

    pthread_t tid ;
    int n = pthread_create(&tid, nullptr, routine, (void*)"thread-1");
    if(n != 0)
    {
        std::cout << "create thread error: " <<strerror(n) <<std::endl;
        return 1;
    }

    while(true)
    {
        std::cout << "我是main线程..." <<std::endl;
        sleep(1);
    }
    return 0;
}